#ifndef __SQLITE_BASE_TABLE_H_
#define __SQLITE_BASE_TABLE_H_

#include "sqlite-sql-executor.h"
#include "sqlite-sql-command.h"
#include <vector>
#include <deque>
#include <set>
#include <list>
#include <map>

#define SQLITE_INVAILD_CONNECTID -1

typedef enum {
    BASIC_INFORMATION_TABLE = 0,
    OSD_CONFIG_TABLE = 1,
    PRESET_TABLE = 2,
    PGUSER_TABLE = 3,
    ONVIFUSER_TABLE = 4,
    PG_OSD_TABLE = 5,
    PGLOGMANAGER_TABLE = 6,
    VIDEO_RECORDFILE_TABLE = 7,
    JPG_RECORDFILE_TABLE = 8,
    USER_MANAGER_TABLE = 9,
    PRESET_TEXT_TABLE = 10,

    MAX_TABLE = 11,
}Table_E;

enum
{
    TableError_OK = 0,
    TableError_KeyHasExist = 1,
    TableError_AllocMemFailed = 2,
    TableError_AddChildFailed = 3,
    TableError_SQLExecFailed = 4,
};

#define TABLE_LOADFIELD_INT(field, val)\
    do{\
        std::string str_field = field;\
        if (!pRS->get_field_value(str_field, i_value)){\
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE,"load field %s failed.\n", field);\
            return false;\
        }\
        val = i_value;\
    }while( 0 );

#define TABLE_LOADFIELD_INT64(field, val)\
    do{\
        std::string str_field = field;\
        if (!pRS->get_field_value(str_field, i_value_64)){\
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE,"load field %s failed.\n", field);\
            return false;\
        }\
        val = i_value_64;\
    }while( 0 );

#define TABLE_LOADFIELD_STR(field, val)\
    do{\
        std::string str_field = field;\
        if (!pRS->get_field_value(str_field, str_value)) {\
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE,"load field %s failed.", field);\
            return false;\
        }\
        val = str_value;\
    }while( 0 );

class table_int_index_manager
{
public:
    table_int_index_manager()
        : mui_current_table_index(0)
    {

    }

    virtual ~table_int_index_manager()
    {

    }

    void set_table_index(const unsigned int &ui_index)
    {
        std::lock_guard<std::mutex> guard( mo_index_lock );
        if (ui_index > mui_current_table_index) {
            mui_current_table_index = ui_index;
        }
    }

    unsigned int get_table_index()
    {
        std::lock_guard<std::mutex> guard( mo_index_lock );
        mui_current_table_index++;
        return mui_current_table_index;
    }

    void init()
    {
        std::lock_guard<std::mutex> guard( mo_index_lock );
        mui_current_table_index = 0;
    }

    bool is_uninit(const unsigned int& ui_index)
    {
        return 0 == ui_index;
    }

private:
    std::mutex     mo_index_lock;
    unsigned int   mui_current_table_index;
};

class sqlite_base_table
{
public:
    sqlite_base_table( const int i_table_id, const std::string &str_table_name )
        : mi_connect_id( SQLITE_INVAILD_CONNECTID )
        , mi_table_id( i_table_id )
        , mstr_table_name( str_table_name )
        , mp_excutor(NULL)
    {
        mstr_sql = "select * from " + str_table_name;
    }

    virtual ~sqlite_base_table() {

    }

    void set_connect_id( const int id ){
        mi_connect_id = id;
    }

    virtual void set_connect_excutor(sql_executor_cmd* p_excutor) {
        mp_excutor = p_excutor;
    }

    virtual int load_from_db(){
        return TableError_SQLExecFailed;
    }

    virtual bool check_table_default_data(){
        return true;
    }

    unsigned int get_table_id(){
        return mi_table_id;
    }

    std::string  get_table_name(){
        return mstr_table_name;
    }

    virtual void get_table_info(st_sql_table_info &TblInfo){
        assert(0);
    }

    virtual bool clear_all_data(){
        assert(0);
        return false;
    }

    virtual bool reset_default() {
        assert(0);
        return false;
    }

protected:
    int          mi_connect_id;
    unsigned int mi_table_id;
    std::string  mstr_table_name;
    std::string  mstr_sql;
    sql_executor_cmd* mp_excutor;
};

template<typename KEY, typename VALUE_ITEM>
class sqlite_base_table_handler : public sqlite_base_table
{
public:
    sqlite_base_table_handler( const int i_table_id, const std::string &str_table_name, bool b_auto_key = true )
        : sqlite_base_table( i_table_id, str_table_name )
        , mb_is_auto_primary_key( b_auto_key )
    {
        pthread_rwlock_init( &m_table_rw_lock, NULL );
    }

    virtual ~sqlite_base_table_handler(){
        clear_table_items();
        pthread_rwlock_destroy( &m_table_rw_lock );
    }

public:
    bool get_all_index( std::set<KEY> &idx_set )
    {
        pthread_rwlock_rdlock( &m_table_rw_lock );
        typename std::map<KEY, VALUE_ITEM *>::iterator it =m_table_item_map.begin();
        for( ; it != m_table_item_map.end(); ++it ){
            VALUE_ITEM *p_item = it->second;
            idx_set.insert( p_item->key() );
        }
        pthread_rwlock_unlock( &m_table_rw_lock );

        return true;
    }

    bool get_all_index( std::vector<KEY> &idx_vec )
    {
        pthread_rwlock_rdlock( &m_table_rw_lock );
        typename std::map<KEY, VALUE_ITEM *>::iterator it =m_table_item_map.begin();
        for( ; it != m_table_item_map.end(); ++it ){
            VALUE_ITEM *p_item = it->second;
            idx_vec.push_back( p_item->key() );
        }
        pthread_rwlock_unlock( &m_table_rw_lock );
        return true;
    }

    bool copy_list( std::map<KEY, VALUE_ITEM> &item_map, const bool b_lock )
    {
        if( b_lock ){
            pthread_rwlock_rdlock( &m_table_rw_lock );
            typename std::map<KEY, VALUE_ITEM *>::iterator it = m_table_item_map.begin();
            for( ; it !=m_table_item_map.end(); ++it ){
                VALUE_ITEM *p_item = it->second;
                if( p_item != NULL ){
                    item_map[it->first] = *p_item;
                }
            }
            pthread_rwlock_unlock( &m_table_rw_lock );
        } else {
            typename std::map<KEY, VALUE_ITEM *>::iterator it = m_table_item_map.begin();
            for( ; it !=m_table_item_map.end(); ++it ){
                VALUE_ITEM *p_item = it->second;
                if( p_item != NULL ){
                    item_map[it->first] = *p_item;
                }
            }
        }

        return true;
    }

    template<typename COLL>
    bool copy_list( COLL &item_list, const bool b_lock )
    {
        if( b_lock ){
            pthread_rwlock_rdlock( &m_table_rw_lock );
            typename std::map<KEY, VALUE_ITEM *>::iterator it = m_table_item_map.begin();
            for( ; it !=m_table_item_map.end(); ++it ){
                VALUE_ITEM *p_item = it->second;
                if( p_item != NULL ){
                    item_list.push_back( *p_item );
                }
            }
            pthread_rwlock_unlock( &m_table_rw_lock );
        } else {
            typename std::map<KEY, VALUE_ITEM *>::iterator it = m_table_item_map.begin();
            for( ; it !=m_table_item_map.end(); ++it ){
                VALUE_ITEM *p_item = it->second;
                if( p_item != NULL ){
                    item_list.push_back( *p_item );
                }
            }
        }

        return true;
    }

    unsigned int get_count()
    {
        pthread_rwlock_rdlock( &m_table_rw_lock );
        unsigned int ui_count = m_table_item_map.size();
        pthread_rwlock_unlock( &m_table_rw_lock );

        return ui_count;
    }

    bool load_max_key_from_db( std::string &str_name, KEY &max_key )
    {
        if (str_name.empty()) {
            return false;
        }

        std::string str_sql = "select max([" + str_name + "]) from " + mstr_table_name;

        st_sql_record *pRS = NULL;
        int i_result = 0;
        bool b_ret = mp_excutor->executor_sql(str_sql, &pRS, i_result);
        if ( (false == b_ret) || (NULL == pRS) ) {
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "LoadMaxIndexFromDB ExecCmd return %d. SQL=%s\n", b_ret, str_sql.c_str());
            mp_excutor->close_rs(pRS);
            return false;
        }

        std::string str_field = "max([" + str_name + "])";
        while ( !pRS->is_eof() ) {
            if (!pRS->get_field_value(str_field, max_key)) {
                mp_excutor->close_rs(pRS);
                return false;
            }

            pRS->move_next();
        }

        b_ret = mp_excutor->close_rs(pRS);

        if (false == b_ret) {
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "LoadTable CloseRS return %d.\n", b_ret);
            return false;
        }

        return b_ret;
    }

    virtual int load_from_db()
    {
        int i_ret = TableError_OK;

        clear_table_items();

        base_auto_rw_lock<pthread_rwlock_t, false> guard( &m_table_rw_lock );

        mst_table_index_manager.init();

        st_sql_record *pRs = NULL;
        int i_result = 0;
        bool b_ret_exec = mp_excutor->executor_sql(mstr_sql, &pRs, i_result);
        if( !b_ret_exec || (NULL == pRs) ){
            i_ret = TableError_SQLExecFailed;
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load_from_db executor_cmd failed. return %d, sql=%s\n", i_ret, mstr_sql.c_str() );
            return i_ret;
        }

        std::list<VALUE_ITEM> del_item_lists;
        while( !pRs->is_eof() ){            
            VALUE_ITEM item;
            if( !load_from_rs( pRs, item ) ){
                i_ret = TableError_SQLExecFailed;
                HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "Load_from_db load_from_rs failed.\n" );
                mp_excutor->close_rs( pRs );
                return i_ret;
            }

            if( !add_item( item, i_ret ) ){
                std::string str_sql;
                create_insert_sql( item, str_sql );
                if( !str_sql.empty() ){
                    HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load_from_db add_item failed. ret=%d, sql=%s\n", i_ret, str_sql.c_str() );
                }
                if( i_ret == TableError_AddChildFailed ){
                    del_item_lists.push_back( item );
                } else {
                    mp_excutor->close_rs( pRs );
                    return i_ret;
                }
            }

            pRs->move_next();
        }        

        mp_excutor->close_rs( pRs );

        if( !del_item_lists.empty() ){
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load_from_db data logic error\n" );

            std::vector<std::string> str_del_sql_vec;
            typename std::list<VALUE_ITEM>::iterator it = del_item_lists.begin();
            for( ; it != del_item_lists.end(); ++it ){
                create_delete_sql( *it, str_del_sql_vec );
            }

            std::vector<std::string>::iterator it_sql = str_del_sql_vec.begin();
            for( ; it_sql != str_del_sql_vec.end(); ++it_sql ){
                HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "remove redundant %s\n", (*it_sql).c_str() );
            }

            if( !execute_sql( str_del_sql_vec ) ){
                i_ret = TableError_SQLExecFailed;
            }
        }

        return i_ret;
    }

    template<typename T, typename LIST>
    bool load_list_from_db(LIST &list, std::string str_sql = "")
    {
        HK_LOG_INFO_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load_list_from_db\n");

        st_sql_record *pRS = NULL;
        bool b_ret = false;
        if ( !str_sql.empty() ) {
            int i_result = 0;
            b_ret = mp_excutor->executor_sql(str_sql, &pRS, i_result);
        } else {
            str_sql = mstr_sql;
            int i_result = 0;
            b_ret = mp_excutor->executor_sql(str_sql, &pRS, i_result);
        }

        if ( (false == b_ret) || (NULL == pRS) ) {
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load_list_from_db executor_cmd return %d. sql=%s\n", b_ret, str_sql.c_str() );
            mp_excutor->close_rs( pRS );
            return false;
        }

        while (!pRS->is_eof()) {
            T item;
            if ( !load_from_rs(pRS, item) ) {
                HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE,"load_list_from_db load_from_rs Failed.\n");
                mp_excutor->close_rs( pRS );
                return false;
            }

            list.push_back(item);
            pRS->move_next();
        }

        b_ret = mp_excutor->close_rs( pRS );
        if (false == b_ret) {
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "LoadTable CloseRS return %d.\n", b_ret );
            return false;
        }

        return b_ret;
    }

    template<typename T, typename LIST, typename Func>
    bool load_list_from_db(LIST &list, Func &func , std::string str_sql = "")
    {
        HK_LOG_INFO_EX(HK_MACHINE_LOG_SUFFIX_FILE,  "LoadListFromDB_Fun Table\n" );

        std::string str_sql_exec;
        if ( !str_sql.empty() ) {
            str_sql_exec = str_sql;
        } else {
            str_sql_exec = mstr_sql;
        }

        st_sql_record *pRS = NULL;
        int i_result = 0;
        bool b_ret = mp_excutor->executor_sql(str_sql_exec, &pRS, i_result);
        if ( (false == b_ret) || (NULL == pRS) ) {
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load_list_from_db executor_cmd return %d. SQL=%s\n", b_ret, str_sql_exec.c_str()) ;
            mp_excutor->close_rs( pRS );
            return false;
        }

        while (!pRS->is_eof()) {
            T item;
            if (!load_from_rs(pRS, item)) {
                HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE,"load_list_from_db load_from_rs Failed.\n");
                mp_excutor->close_rs( pRS );
                return false;
            }

            if (!func(list, item))  {
                break;
            }

            pRS->move_next();
        }

        b_ret = mp_excutor->close_rs( pRS );
        if (false == b_ret) {
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "load_list_from_db close_rs return %d.\n", b_ret);
            return false;
        }

        return b_ret;
    }

    bool insert_item( VALUE_ITEM &new_item, bool b_check_key = true )
    {
        base_auto_rw_lock<pthread_rwlock_t, false> guard( &m_table_rw_lock );
        if( b_check_key ){
            if( is_uninit_key(new_item.key()) ){
                new_item.key( mst_table_index_manager.get_table_index() );
            }
        }        

        std::string str_sql;
        create_insert_sql( new_item, str_sql );
        if( !execute_sql( str_sql ) ){
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "insert_item execute_sql failed. sql=%s\n", str_sql.c_str() );
            return false;
        }

        int i_ret = TableError_OK;
        if( !add_item( new_item, i_ret ) ){
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "insert_item add_item failed. ret=%d\n", i_ret );

            if( TableError_AddChildFailed == i_ret ){
                HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "insert_item data logic error\n");

                std::vector<std::string> str_sql_vec;
                create_delete_sql(new_item, str_sql_vec);

                std::vector<std::string>::iterator it = str_sql_vec.begin();
                for (; it != str_sql_vec.end(); ++it){
                    HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "insert_item del_sql:%s\n", (*it).c_str() );
                }

                if ( !execute_sql(str_sql_vec) ) {
                    HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "insert_item del execute_sql Failed.\n" );
                }
            }

            return false;
        }

        system("sync");//add by xjcai@20180720103400, sync after io operation success.

        return true;
    }

    bool update_item( const VALUE_ITEM item )
    {
        base_auto_rw_lock<pthread_rwlock_t, false> guard( &m_table_rw_lock );
        std::string str_sql;
        create_update_sql( item, str_sql );

        if( !execute_sql( str_sql ) ){
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "update_item execute_sql failed. sql=%s\n", str_sql.c_str() );
            return false;
        }

        if( !del_item( item ) ){
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "update_item del_item failed. sql=%s\n",str_sql.c_str() );
            return false;
        }

        int i_ret = TableError_OK;
        if( !add_item( item, i_ret ) ){
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "update_item add_item failed. ret=%d, sql=%s\n", i_ret, str_sql.c_str() );
            return false;
        }

        system("sync");//add by xjcai@20180720103400, sync after io operation success.

        return true;
    }

    bool delete_item_by_key( const KEY &key )
    {
        base_auto_rw_lock<pthread_rwlock_t, false> guard( &m_table_rw_lock );
        typename std::map<KEY, VALUE_ITEM*>::iterator it = m_table_item_map.find( key );
        if( it == m_table_item_map.end() ){
            return false;
        }

        VALUE_ITEM *p_item = it->second;
        return delete_item( *p_item, false );
    }


    bool delete_item( const VALUE_ITEM item, bool b_lock = true )
    {
        if( b_lock ){
            pthread_rwlock_wrlock( &m_table_rw_lock );
        }

        bool b_ret = true;
        std::vector<std::string> str_sql_vec;
        create_delete_sql( item, str_sql_vec );
        if( !execute_sql( str_sql_vec ) )            {
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "delete_item execute_sql Failed.\n" );
            b_ret = false;
        }

        if( b_ret ){
            if( !del_item( item ) ){
                HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "delete_item del_item Failed.\n" );
                b_ret = false;
            }
        }

        if( b_lock ){
            pthread_rwlock_unlock( &m_table_rw_lock );
        }

        return b_ret;
    }

    bool update_item( const KEY &key, VALUE_ITEM &item )
    {
        pthread_rwlock_wrlock( &m_table_rw_lock );
        typename std::map<KEY, VALUE_ITEM*>::iterator it = m_table_item_map.find( key );
        if( it == m_table_item_map.end() ){
            pthread_rwlock_unlock( &m_table_rw_lock );
            return insert_item( item );
        }

        VALUE_ITEM *p_item = it->second;
        if( item == *p_item ){
            pthread_rwlock_unlock( &m_table_rw_lock );
            return true;
        }

        pthread_rwlock_unlock( &m_table_rw_lock );
        return update_item( item );
    }

    bool find_table_item( const KEY &key )
    {
        base_auto_rw_lock<pthread_rwlock_t> guard( &m_table_rw_lock );
        typename std::map<KEY, VALUE_ITEM*>::iterator it = m_table_item_map.find( key );
        if( it == m_table_item_map.end() ){
            return false;
        }

        return true;
    }

    bool find_table_item( const KEY &key, VALUE_ITEM &item, const bool b_rdLock = true )
    {
        if( b_rdLock ){
            base_auto_rw_lock<pthread_rwlock_t> guard( &m_table_rw_lock );
            typename std::map<KEY, VALUE_ITEM*>::iterator it = m_table_item_map.find( key );
            if( it == m_table_item_map.end() ){
                return false;
            }

            VALUE_ITEM *p_item = it->second;
            if( NULL == p_item ){
                return false;
            }

            item = *p_item;
        } else {
            base_auto_rw_lock<pthread_rwlock_t, false> guard( &m_table_rw_lock );
            typename std::map<KEY, VALUE_ITEM*>::iterator it = m_table_item_map.find( key );
            if( it == m_table_item_map.end() ){
                return false;
            }

            VALUE_ITEM *p_item = it->second;
            if( NULL == p_item ){
                return false;
            }

            item = *p_item;
        }

        return true;
    }

    template<typename KEYLIST>
    bool find_table_item( const KEYLIST &key_list, std::list<VALUE_ITEM> &item_list )
    {
        base_auto_rw_lock<pthread_rwlock_t> guard( &m_table_rw_lock );
        typename KEYLIST::iterator it = key_list.begin();
        for( ; it != key_list.end(); ++it ){
            typename std::map<KEY, VALUE_ITEM*>::iterator it_find = m_table_item_map.find( *it );
            if( it_find == m_table_item_map.end() ){
                continue;
            }

            VALUE_ITEM *p_item = it_find->second;
            if( NULL == p_item ){
                continue;
            }

            item_list.push_back( *p_item );
        }

        return true;
    }

    bool reload_table( const bool b_reload_ref_tbl = true )
    {
        HK_LOG_INFO_EX(HK_MACHINE_LOG_SUFFIX_FILE, "[%s]: b_reload_ref_tbl = %d.\n", __func__, b_reload_ref_tbl ? 1:0);
        do{
            int i_ret = load_from_db();
            if( i_ret != TableError_OK ){
                HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "reload_table load_from_db failed. ret = %d, sql=%s\n", i_ret, mstr_sql.c_str() );
                return false;
            }
        } while( 0 );

        return true;
    }

    bool re_flash_db()
    {
        std::vector<std::string> str_sql_vec;
        do{
            base_auto_rw_lock<pthread_rwlock_t, false> guard( &m_table_rw_lock );
            typename std::map<KEY, VALUE_ITEM&>::iterator it = m_table_item_map.begin();
            for( ; it != m_table_item_map.end(); ++it ){
                std::string str_sql;
                create_update_sql( *(it->second), str_sql );
                str_sql_vec.push_back( str_sql );
            }
        }while( 0 );

        return execute_sql( str_sql_vec );
    }

    template<typename LIST>
    bool insert_items( LIST &item_list )
    {
        if( item_list.empty() ){
            return true;
        }

        std::vector<std::string> str_sql_vec;

        bool b_ret = true;

        do{
            base_auto_rw_lock<pthread_rwlock_t, false> guard( &m_table_rw_lock );
            typename LIST::iterator it = item_list.begin();
            for( ; it != item_list.end(); ++it ){
                VALUE_ITEM &item = *it;
                if( mst_table_index_manager.is_uninit( item.key() ) ){
                    item.key( mst_table_index_manager.get_table_index() );
                }

                std::string str_sql;
                create_insert_sql( item, str_sql );
                str_sql_vec.push_back( str_sql );

                int i_ret = 0;
                if( !add_item( item, i_ret ) ){
                    HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "insert_items add_item Failed. item=%s\n", str_sql );
                    b_ret = false;
                    break;
                }
            }
        } while( 0 );

        if( !b_ret ){
            reload_table( false );
            return false;
        }

        if( str_sql_vec.empty() ){
            return true;
        }

        if( !execute_sql( str_sql_vec ) ){
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "insert_items execute_sql Failed.\n" );
            reload_table( false );
            return false;
        }

        return true;
    }

    template<typename LIST>
    bool insert_items_ex( LIST &item_list )
    {
        if( item_list.empty() ){
            return true;
        }

        std::vector<std::string> str_sql_vec;
        bool b_ret = true;

        do{
            base_auto_rw_lock<pthread_rwlock_t, false> guard( &m_table_rw_lock );
            typename LIST::iterator it = item_list.begin();
            for( ; it != item_list.end(); ++it ){
                bool b_is_same = false;
                typename std::map<KEY, VALUE_ITEM&>::iterator it_sam = m_table_item_map.begin();
                for( ; it_sam != m_table_item_map.end(); ++it_sam ){
                    VALUE_ITEM *p_item = it_sam->second;
                    if( p_item->compare( *it ) ){
                        b_is_same = true;
                        break;
                    }
                }

                if( b_is_same ){
                    continue;
                }

                VALUE_ITEM &item = *it;
                if( mst_table_index_manager.is_uninit( item.key() ) ){
                    item.key( mst_table_index_manager.get_table_index() );
                }

                std::string str_sql;
                create_insert_sql( item, str_sql );
                str_sql_vec.push_back( str_sql );

                int i_ret = 0;
                if( !add_item( item, i_ret ) ){
                    HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "insert_items add_item Failed. item=%s\n", str_sql );
                    b_ret = false;
                    break;
                }
            }
        }while( 0 );

        if( !b_ret ){
            reload_table( false );
            return false;
        }

        if( str_sql_vec.empty() ){
            return true;
        }

        if( !execute_sql( str_sql_vec ) ){
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "insert_items execute_sql Failed.\n" );
            reload_table( false );
            return false;
        }

        return true;
    }

    template<typename FUNC>
    bool update_items_func( FUNC &func )
    {
        std::vector<std::string> str_sql_vec;
        do{
            base_auto_rw_lock<pthread_rwlock_t, false> guard( &m_table_rw_lock );
            typename std::map<KEY, VALUE_ITEM*>::iterator it = m_table_item_map.begin();
            for( ; it != m_table_item_map.end(); ++it ){
                VALUE_ITEM *p_item = it->second;
                if( func( *p_item ) ){
                    std::string str_sql_temp;
                    create_update_sql( *p_item, str_sql_temp );
                    str_sql_vec.push_back( str_sql_temp );
                }
            }

            if( str_sql_vec.empty() ){
                return true;
            }
        }while( 0 );

        if( !execute_sql( str_sql_vec ) ){
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "delete_items_func execute_sql Failed.\n" );
            reload_table( false );
            return false;
        }

        return true;
    }

    template<typename LIST, typename FUNC>
    bool update_items_func( const LIST &item_list, const FUNC &func )
    {
        std::vector<std::string> str_sql_vec;
        do{
            base_auto_rw_lock<pthread_rwlock_t, false> guard( &m_table_rw_lock );
            typename LIST::const_iterator it = item_list.begin();
            for( ; it != item_list.end(); ++it ){
                typename std::map<KEY, VALUE_ITEM*>::iterator it_find = m_table_item_map.find( it->key() );
                if( it_find != m_table_item_map.end() ){
                    VALUE_ITEM *p_item = it_find->second;
                    if( func( *p_item ) ){
                        std::string str_sql_temp;
                        create_update_sql( *p_item, str_sql_temp );
                        str_sql_vec.push_back( str_sql_temp );
                    }
                }
            }

            if( str_sql_vec.empty() ){
                return true;
            }
        }while( 0 );

        if( !execute_sql( str_sql_vec ) ){
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "delete_items_func execute_sql Failed.\n" );
            reload_table( false );
            return false;
        }

        return true;
    }

    template<typename FUNC>
    bool update_items_func( const std::vector<KEY> &key_list, const FUNC &func )
    {
        std::vector<std::string> str_sql_vec;
        do{
            base_auto_rw_lock<pthread_rwlock_t, false> guard( &m_table_rw_lock );
            typename std::vector<KEY>::const_iterator it = key_list.begin();
            for( ; it != key_list.end(); ++it ){
                typename std::map<KEY, VALUE_ITEM*>::iterator it_find = m_table_item_map.find( *it );
                if( it_find != m_table_item_map.end() ){
                    VALUE_ITEM *p_item = it_find->second;
                    if( func( *p_item ) ){
                        std::string str_sql_temp;
                        create_update_sql( *p_item, str_sql_temp );
                        str_sql_vec.push_back( str_sql_temp );
                    }
                }
            }
        }while( 0 );

        if( str_sql_vec.empty() ){
            return true;
        }

        if( !execute_sql( str_sql_vec ) ){
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "delete_items_func execute_sql Failed.\n" );
            reload_table( false );
            return false;
        }

        return true;
    }

    bool delete_items( const std::vector<KEY> &key_vec )
    {
        std::vector<std::string> str_sql_vec;
        bool b_ret = true;

        do{
            base_auto_rw_lock<pthread_rwlock_t, false> guard( &m_table_rw_lock );
            typename std::vector<KEY>::const_iterator it = key_vec.begin();
            for( ; it != key_vec.end(); ++it ){
                typename std::map<KEY, VALUE_ITEM*>::iterator it_find = m_table_item_map.find( *it );
                if( it_find != m_table_item_map.end() ){
                    VALUE_ITEM *p_item = it_find->second;
                    assert( p_item != NULL );

                    std::vector<std::string> str_vec_temp;
                    create_delete_sql( *p_item, str_vec_temp );
                    MergeList( str_sql_vec, str_vec_temp );

                    if( !del_item( *p_item ) ){
                        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "delete_items del_item Failed.\n" );
                        b_ret = false;
                        break;
                    }
                }
            }
        }while( 0 );

        if( !b_ret ){
            reload_table( false );
            return false;
        }

        if( str_sql_vec.empty() ){
            return true;
        }

        if( !execute_sql( str_sql_vec ) ){
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "delete_items execute_sql Failed.\n" );
            reload_table( false );
            return false;
        }

        return true;
    }

    bool delete_items( const std::map<KEY, VALUE_ITEM> &map_item )
    {
        std::vector<std::string> str_sql_vec;
        bool b_ret = true;

        do{
            base_auto_rw_lock<pthread_rwlock_t, false> guard( &m_table_rw_lock );
            typename std::map<KEY, VALUE_ITEM>::const_iterator it = map_item.begin();
            for( ; it != map_item.end(); ++it ){
                const VALUE_ITEM &item = it->second;
                if( !del_item( item ) ){
                    HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "delete_items del_item Failed.\n" );
                    b_ret = false;
                    break;
                }

                std::vector<std::string> str_vec_temp;
                create_delete_sql( item, str_vec_temp );
                MergeList( str_sql_vec, str_vec_temp );
            }
        }while( 0 );

        if( !b_ret ){
            reload_table( false );
            return false;
        }

        if( str_sql_vec.empty() ){
            return true;
        }

        if( !execute_sql( str_sql_vec ) ){
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "delete_items execute_sql Failed.\n" );
            reload_table( false );
            return false;
        }

        return true;
    }

    template<typename FUNC>
    bool delete_items_func( FUNC &func )
    {
        bool b_ret = true;
        std::vector<std::string> str_sql_vec;

        do{
            base_auto_rw_lock<pthread_rwlock_t, false> guard( &m_table_rw_lock );
            typename std::map<KEY, VALUE_ITEM*>::iterator it = m_table_item_map.begin();
            for( ; it != m_table_item_map.end();  ){
                VALUE_ITEM *p_item = it->second;
                if( !func( *p_item ) ){
                    ++it;
                } else {
                    if( !del_child_key( p_item ) ){
                        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "delete_items_func del_child_key Failed.\n" );
                        b_ret = false;
                        break;
                    }

                    std::vector<std::string> str_sql_temp;
                    create_delete_sql( *p_item, str_sql_temp );
                    MergeList( str_sql_vec, str_sql_temp );

                    delete p_item;
                    p_item = NULL;
                    it = m_table_item_map.erase( it );
                }
            }
        }while( 0 );

        if( !b_ret ){
            reload_table( false );
            return true;
        }

        if( str_sql_vec.empty() ){
            return true;
        }

        if( !execute_sql( str_sql_vec ) ){
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "delete_items_func execute_sql Failed.\n" );
            reload_table( false );
            return false;
        }

        return true;
    }

    void clear_table_items()
    {
        base_auto_rw_lock<pthread_rwlock_t, false> guard( &m_table_rw_lock );
        typename std::map<KEY, VALUE_ITEM*>::iterator it = m_table_item_map.begin();
        for( ; it != m_table_item_map.end(); ++it ){
            VALUE_ITEM *p_item = it->second;
            if( p_item != NULL ){
                if( !del_child_key( p_item ) ){
                    HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "clear_table_items del_child_key failed.\n" );
                }

                delete p_item;
                p_item = NULL;
            } else {
                HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "clear_table_items item is null.\n" );
            }
        }
        m_table_item_map.clear();
    }

    bool clear_all_data()
    {
        std::string str_sql = "delete from " + mstr_table_name;
        if( !execute_sql( str_sql ) ){
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "clear_all_data Failed.\n" );
            return false;
        }

        clear_table_items();
        return true;
    }

    bool reset_default() {
        bool clear_ret = clear_all_data();
        if(clear_ret) {
            bool reload_default_ret = check_table_default_data();
            if(reload_default_ret) {
                return true;
            }
        }

        return false;
    }

    template<typename LIST, typename FUNC>
    bool get_list( LIST &list, FUNC &func )
    {
        base_auto_rw_lock<pthread_rwlock_t> guard( &m_table_rw_lock );
        typename std::map<KEY, VALUE_ITEM*>::iterator it = m_table_item_map.begin();
        for( ; it != m_table_item_map.end(); ++it ) {
            VALUE_ITEM *p_item = it->second;
            if( p_item && func( *p_item ) ){
                list.push_back( *p_item );
            }
        }

        return true;
    }

    template<typename MAP, typename FUNC>
    bool get_map( MAP &map, FUNC &func )
    {
        base_auto_rw_lock<pthread_rwlock_t> guard( &m_table_rw_lock );
        typename std::map<KEY, VALUE_ITEM*>::iterator it = m_table_item_map.begin();
        for( ; it != m_table_item_map.end(); ++it ) {
            VALUE_ITEM *p_item = it->second;
            if( p_item && func( *p_item ) ){
                map[p_item->key()] = *p_item;
            }
        }

        return true;
    }

    template<typename FUNC>
    bool for_each( FUNC &func, bool b_rd_lock = true )
    {
        if( b_rd_lock ){
            base_auto_rw_lock<pthread_rwlock_t> guard( &m_table_rw_lock );
            typename std::map<KEY, VALUE_ITEM*>::iterator it = m_table_item_map.begin();
            for( ; it != m_table_item_map.end(); ++it ) {
                VALUE_ITEM *p_item = it->second;
                if( (NULL == p_item) || !func( *p_item ) ){
                    return false;
                }
            }
        } else {
            base_auto_rw_lock<pthread_rwlock_t, false> guard( &m_table_rw_lock );
            typename std::map<KEY, VALUE_ITEM*>::iterator it = m_table_item_map.begin();
            for( ; it != m_table_item_map.end(); ++it ) {
                VALUE_ITEM *p_item = it->second;
                if( (NULL == p_item) || !func( *p_item ) ){
                    return false;
                }
            }
        }


        return true;
    }

    template<typename SET, typename FUNC>
    void get_item_key_set( SET &set, FUNC &func )
    {
        base_auto_rw_lock<pthread_rwlock_t> guard( &m_table_rw_lock );
        typename std::map<KEY, VALUE_ITEM*>::iterator it = m_table_item_map.begin();
        for( ; it != m_table_item_map.end(); ++it ) {
            VALUE_ITEM *p_item = it->second;
            if( p_item && func( *p_item ) ){
                set.insert( p_item->key() );
            }
        }
    }

protected:
    bool add_item( const VALUE_ITEM &item, int &i_ret )
    {
        typename std::map<KEY, VALUE_ITEM*>::iterator it =  m_table_item_map.find( item.key() );
        if( it != m_table_item_map.end() ){
            i_ret = TableError_KeyHasExist;
            HK_LOG_INFO_EX(HK_MACHINE_LOG_SUFFIX_FILE,  "add item failed. key is exist!\n" );
            return false;
        }

        VALUE_ITEM *p_new = new VALUE_ITEM( item );
        if( !p_new ){
            i_ret = TableError_AllocMemFailed;
            HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "add_item alloc failed. pnew is null.\n" );
            return false;
        }

        m_table_item_map[p_new->key()] = p_new;

        if( !add_child_key( p_new ) ){
            i_ret = TableError_AddChildFailed;
            std::string str_sql;
            create_insert_sql( item, str_sql );
            if( !str_sql.empty() ){
                HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE, "add_child_key failed. sql=%s\n", str_sql.c_str() );
            }

            m_table_item_map.erase( p_new->key() );

            delete p_new;
            p_new = NULL;

            return false;
        }

        mst_table_index_manager.set_table_index( p_new->key() );

        return true;
    }

    bool del_item(const VALUE_ITEM item)
    {
        bool b_ret = true;
        typename std::map<KEY, VALUE_ITEM*>::iterator it =  m_table_item_map.find( item.key() );
        if (it == m_table_item_map.end()) {
            return false;
        }

        VALUE_ITEM* p_item = it->second;
        if (p_item) {
            if ( !del_child_key( p_item ) ){
                b_ret = false;
            }
        }

        delete p_item;
        p_item = NULL;

        m_table_item_map.erase(it);

        return b_ret;
    }

    virtual bool add_child_key( VALUE_ITEM *p_new ){ return true; }
    virtual bool del_child_key( VALUE_ITEM *p_new ){ return true; }


    template<typename Func>
    void get_item_list_by_func(std::list<VALUE_ITEM*> &item_list, Func fun, bool b_lock = true)
    {
        if (b_lock)
        {
            base_auto_rw_lock<pthread_rwlock_t, false> guard( &m_table_rw_lock );
            typename std::map<KEY, VALUE_ITEM*>::iterator it = m_table_item_map.begin();
            for (; it != m_table_item_map.end(); ++it) {
                VALUE_ITEM *p_item = it->second;
                if (fun(*p_item)) {
                    item_list.push_back(p_item);
                }
            }
        } else {
            typename std::map<KEY, VALUE_ITEM*>::iterator it = m_table_item_map.begin();
            for (; it != m_table_item_map.end(); ++it) {
                VALUE_ITEM *p_item = it->second;
                if (fun(*p_item)) {
                    item_list.push_back(p_item);
                }
            }
        }
    }

    bool execute_sql(const std::vector<std::string> &str_sql_list)
    {
        if( str_sql_list.empty() ){
            return true;
        }

        return mp_excutor->batch_executor(str_sql_list);
    }

    bool execute_sql(const std::deque<std::string> &str_sql_list)
    {
        if( str_sql_list.empty ){
            return true;
        }

        return mp_excutor->batch_executor(str_sql_list);
    }

    bool execute_sql(std::string &str_sql)
    {
        if( str_sql.empty() ){
            return true;
        }

        int i_result = 0;
        return mp_excutor->executor_cmd(str_sql, i_result);
    }

    bool execute_sql(std::string &str_sql, int &i_effect_row)
    {
        if( str_sql.empty ){
            return true;
        }

        int i_result = 0;
        return mp_excutor->executor_cmd(str_sql, i_result, i_effect_row);
    }


    virtual bool load_from_rs( st_sql_record *pRs, VALUE_ITEM &item ){ return false; }

    virtual void create_insert_sql(const VALUE_ITEM& Item, std::string& str_sql)
    {
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE,"create_insert_sql Failed.\n");
        //assert(0);
    }

    virtual void create_update_sql(const VALUE_ITEM& Item, std::string& str_sql)
    {
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE,"create_update_sql Failed.\n");
        //assert(0);
    }

    virtual void create_delete_sql(const VALUE_ITEM& Item, std::vector<std::string>& str_sql_vec)
    {
        HK_LOG_ERROR_EX(HK_MACHINE_LOG_SUFFIX_FILE,"create_delete_sql Failed.\n");
        //assert(0);
    }

    bool is_uninit_key(const KEY &key)
    {
        if (mb_is_auto_primary_key) {
            return mst_table_index_manager.is_uninit(key);
        }

        return false;
    }

protected:
    bool mb_is_auto_primary_key;

    pthread_rwlock_t m_table_rw_lock;
    typename std::map<KEY, VALUE_ITEM*> m_table_item_map;
    table_int_index_manager mst_table_index_manager;
};

#endif
